"""Reusable Streamlit components for ChatWithRepository."""

import streamlit as st
from typing import Dict, Any, List
import json

class RepositoryCard:
    """A reusable component for displaying repository information."""
    
    @staticmethod
    def display(repo_data: Dict[str, Any], key: str = None):
        """Display a repository card."""
        
        with st.container():
            col1, col2, col3 = st.columns([3, 1, 1])
            
            with col1:
                st.markdown(f"**{repo_data['name']}**")
                st.caption(repo_data['path'])
            
            with col2:
                if repo_data['indexed']:
                    st.success("Indexed")
                else:
                    st.error("Not Indexed")
            
            with col3:
                if repo_data['indexed']:
                    st.metric("Chunks", repo_data['chunks'])

class QueryHistory:
    """Component for displaying query history."""
    
    @staticmethod
    def display(messages: List[Dict[str, str]]):
        """Display query history."""
        
        if not messages:
            st.info("No queries yet. Start chatting!")
            return
        
        for i, message in enumerate(messages[-10:]):  # Show last 10 messages
            if message["role"] == "user":
                st.markdown(f"**🧑 User:** {message['content']}")
            else:
                st.markdown(f"**🤖 Assistant:**")
                st.markdown(message["content"])
                st.divider()

class CodeDisplay:
    """Component for displaying code snippets."""
    
    @staticmethod
    def display_code(code: str, language: str = "python", filename: str = None):
        """Display code with syntax highlighting."""
        
        if filename:
            st.caption(f"📄 {filename}")
        
        st.code(code, language=language)
    
    @staticmethod
    def display_function_info(function_data: Dict[str, Any]):
        """Display function information."""
        
        col1, col2 = st.columns(2)
        
        with col1:
            st.markdown("**Function Details**")
            st.write(f"**Name:** {function_data.get('name', 'N/A')}")
            st.write(f"**Language:** {function_data.get('language', 'N/A')}")
            st.write(f"**File:** {function_data.get('file_path', 'N/A')}")
            st.write(f"**Lines:** {function_data.get('start_line', 'N/A')}-{function_data.get('end_line', 'N/A')}")
        
        with col2:
            st.markdown("**Parameters**")
            params = function_data.get('params', [])
            if params:
                for param in json.loads(params):
                    st.write(f"- {param.get('name', '')}")
            else:
                st.write("No parameters")

class LoadingSpinner:
    """Reusable loading spinner."""
    
    @staticmethod
    def show(text: str = "Loading..."):
        """Show loading spinner with custom text."""
        with st.spinner(text):
            yield

class RepositorySelector:
    """Component for repository selection."""
    
    @staticmethod
    def select(repositories: List[Dict[str, Any]], key: str = "repo_selector") -> str:
        """Create a repository selector dropdown."""
        
        if not repositories:
            st.warning("No repositories available")
            return None
        
        indexed_repos = [repo for repo in repositories if repo['indexed']]
        if not indexed_repos:
            st.warning("No indexed repositories available")
            return None
        
        repo_names = [repo['name'] for repo in indexed_repos]
        selected = st.selectbox(
            "Select Repository",
            ["All Repositories"] + repo_names,
            key=key
        )
        
        return None if selected == "All Repositories" else selected

class ProgressBar:
    """Custom progress bar component."""
    
    @staticmethod
    def show_progress(current: int, total: int, text: str = "Processing..."):
        """Show progress bar."""
        progress = current / total if total > 0 else 0
        st.progress(progress)
        st.caption(f"{text}: {current}/{total}")

class ErrorDisplay:
    """Component for displaying errors."""
    
    @staticmethod
    def show_error(error: Exception, context: str = ""):
        """Display error with context."""
        st.error(f"❌ Error: {str(error)}")
        if context:
            st.info(f"Context: {context}")
    
    @staticmethod
    def show_warning(message: str):
        """Display warning."""
        st.warning(f"⚠️ {message}")
    
    @staticmethod
    def show_success(message: str):
        """Display success message."""
        st.success(f"✅ {message}")

class ChatMessage:
    """Component for chat messages."""
    
    @staticmethod
    def user_message(content: str):
        """Display user message."""
        with st.chat_message("user"):
            st.markdown(content)
    
    @staticmethod
    def assistant_message(content: str):
        """Display assistant message."""
        with st.chat_message("assistant"):
            st.markdown(content)
    
    @staticmethod
    def code_message(code: str, language: str = "python"):
        """Display code message."""
        with st.chat_message("assistant"):
            st.code(code, language=language)

class StatsDashboard:
    """Component for displaying statistics."""
    
    @staticmethod
    def display_stats(repositories: List[Dict[str, Any]]):
        """Display repository statistics."""
        
        col1, col2, col3 = st.columns(3)
        
        total_repos = len(repositories)
        indexed_repos = len([r for r in repositories if r['indexed']])
        total_chunks = sum([r['chunks'] for r in repositories if r['indexed']])
        
        with col1:
            st.metric("Total Repositories", total_repos)
        
        with col2:
            st.metric("Indexed Repositories", indexed_repos)
        
        with col3:
            st.metric("Total Chunks", total_chunks)

class QuickActions:
    """Component for quick action buttons."""
    
    @staticmethod
    def display_actions(callback_func):
        """Display quick action buttons."""
        
        st.subheader("🎯 Quick Actions")
        
        actions = [
            ("What does the main function do?", "🎯"),
            ("Show me error handling examples", "⚠️"),
            ("How is authentication implemented?", "🔐"),
            ("Find database connection code", "🗄️"),
            ("Explain the API endpoints", "🔗"),
            ("Show configuration examples", "⚙️"),
        ]
        
        for query, icon in actions:
            if st.button(f"{icon} {query}", use_container_width=True):
                callback_func(query)

class SettingsPanel:
    """Component for settings management."""
    
    @staticmethod
    def display_settings():
        """Display settings panel."""
        
        st.subheader("⚙️ Settings")
        
        # API Key display
        if Config.KIMI_API_KEY:
            st.success("✅ KIMI API Key configured")
        else:
            st.error("❌ KIMI API Key missing")
        
        # GitHub Token display
        if Config.GITHUB_TOKEN:
            st.success("✅ GitHub Token configured")
        else:
            st.warning("⚠️ GitHub Token optional")
        
        # Directories
        st.info(f"📁 Repos Directory: {Config.REPOS_DIR}")
        st.info(f"🗄️ Vector Database: {Config.CHROMA_PERSIST_DIR}")

# Utility functions for Streamlit
def format_code_for_display(code: str, max_lines: int = 20) -> str:
    """Format code for display with line limit."""
    lines = code.split('\n')
    if len(lines) > max_lines:
        return '\n'.join(lines[:max_lines]) + f"\n... ({len(lines) - max_lines} more lines)"
    return code

def create_download_link(content: str, filename: str, label: str = "Download") -> str:
    """Create a download link for content."""
    import base64
    
    b64 = base64.b64encode(content.encode()).decode()
    return f'<a href="data:text/plain;base64,{b64}" download="{filename}" target="_blank">{label}</a>'

def show_help():
    """Show help information."""
    with st.expander("❓ Help & Usage"):
        st.markdown("""
        ### How to use ChatWithRepository:
        
        1. **Add Repository**: Use the sidebar to add a GitHub repository
        2. **Select Repository**: Choose which repository to query
        3. **Ask Questions**: Use natural language to ask about the code
        4. **Quick Actions**: Use preset queries for common tasks
        
        #### Example Queries:
        - "What does the main function do?"
        - "Show me error handling examples"
        - "How is authentication implemented?"
        - "Find database connection code"
        - "Explain the API endpoints"
        - "Show configuration examples"
        
        #### Supported Languages:
        - Python, JavaScript/TypeScript, Go, Java
        - C/C++, Rust, C#, PHP, Ruby
        """)